<?php

namespace App\Http\Controllers;

use App\Constant\ResponseCode;
use App\Http\Services\ServiceTrait;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;

abstract class ControllerTrait
{
    protected $search = [];
    protected $with = null;
    protected $columns = ['*'];
    protected $defaultSort = ['id' => 'DESC'];
    protected $allowSort = [];
    protected $hidden = [];

    public function search()
    {
        return $this->success($this->getServices()->search($this->search, $this->with, $this->columns, $this->defaultSort, $this->allowSort));
    }

    public function create()
    {
        $request = $this->getRequest('create');
        $services = $this->getServices();
        if (!$data = $services->store($request->validated(),  $this->getUser())) {
            return $this->response($services->getErrors());
        }

        return $this->success($data);
    }

    public function update(int $id)
    {
        $request = $this->getRequest('update');
        $services = $this->getServices();
        if (!$data = $services->update($id, $request->validated(),  $this->getUser())) {
            return $this->response($services->getErrors());
        }

        return $this->success($data);
    }

    public function detail(int $id)
    {
        if (!$data = $this->getServices()->getDetail($id, $this->hidden, $this->with)) {
            return $this->response($this->getServices()->getErrors());
        }

        return $this->success($data);
    }

    public function delete(int $id)
    {
        if (!$this->getServices()->delete($id,  $this->getUser())) {
            return $this->response($this->getServices()->getErrors());
        }

        return $this->success();
    }

    public function batchDelete(string $ids = '')
    {
        if (!$ids) {
            return $this->fail('请选择要删除的数据');
        }

        $ids = explode(',', $ids);
        if (!$count = $this->getServices()->batchDeleteByPrimaryKey($ids)) {
            return $this->response($this->getServices()->getErrors());
        }

        return $this->success("本次共删除【{$count}】条！");
    }

    public function getRequest($name): FormRequest
    {
        $className = str_replace('Controllers', 'Requests', get_class($this)) . '\\' . ucfirst($name) . 'Request';
        if (!class_exists($className)) {
            return $this->fail("未实现：" . $className);
        }

        return app()->make($className);
    }

    /**
     * @return ServiceTrait
     */
    protected function getServices()
    {
        if ($this->_services === null) {
            $className = str_replace('Controllers', 'Services', get_class($this)) . 'Services';
            if (!class_exists($className)) {
                return $this->fail("未实现：" . $className);
            }

            $this->_services = app()->make($className);
        }

        return $this->_services;
    }

    public function success($data = null, $msg = 'ok')
    {
        return $this->response([
            'code' => 200,
            'msg' => $msg,
            'data' => $data,
        ]);
    }

    public function fail($msg = 'fail', $data = null, $code = '-1')
    {
        return $this->response([
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
        ]);
    }

    public function response(array $data)
    {
        throw new HttpResponseException(response()->json($data));
    }

    public function getUser()
    {
        return \Illuminate\Support\Facades\Auth::guard('sanctum')->user();
    }

    public function getUserField($field = null)
    {
        if (!$user = $this->getUser()) {
            return false;
        }

        return $field ? $user->{$field} : $user->toArray();
    }

    public function getLoginUser()
    {
        if (!$user = $this->getUser()) {
            return $this->fail(__('message.请登录'), '', ResponseCode::CODE_NOT_LOGIN);
        }

        return $user;
    }

    public function getLoginUserField($field = null)
    {
        if (!$user = $this->getLoginUser()) {
            return false;
        }

        return $field ? $user->{$field} : $user->toArray();
    }

    protected $_services = null;
}
